/*
 * TMap Designer - A Thematic Map design software
 * Copyright (C) 2006 World Health Organization
 * http://www.who.int
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */
package who.tmap.ui.util;

import java.awt.Container;
import java.io.File;

import javax.swing.JFileChooser;
import javax.swing.JOptionPane;

import org.apache.log4j.Logger;

import who.tmap.bo.Attrs;
import who.tmap.bo.BaseMap;
import who.tmap.bo.BizObjects;
import who.tmap.bo.ThematicMap;
import who.tmap.bo.impl.BizObjectFactory;
import who.tmap.dao.BaseMapDAO;
import who.tmap.dao.impl.DAOFactory;
import who.tmap.imp.dbase.DBaseFile;
import who.tmap.imp.dbase.DBaseFileReader;
import who.tmap.imp.shapefile.ShapeFile;
import who.tmap.imp.shapefile.impl.ShapeFileExport;
import who.tmap.imp.shapefile.impl.ShapeFileImport;
import who.tmap.toolkit.MappingToolKit;
import who.tmap.toolkit.impl.ShapeFileToBaseMapHelper;
import who.tmap.ui.JDialogSelectPolygonNameColumn;
import who.tmap.ui.JFrameMap;
import who.tmap.ui.undo.UndoManager;
import who.tmap.ui.undo.impl.UndoManagerImpl;

/**
 * A Helper for map UI
 * @author stl
 *
 */
public class MapUIHelper extends BaseUIHelper {

    private static Logger logger = Logger.getLogger(MapUIHelper.class);
    
    private static UndoManager undoManager =UndoManagerImpl.getInstance();    
    
    public static final String DEFAULT_JOIN_ID_COLUMN_NAME ="Polygon";
    public static final String DEFAULT_DATA_COLUMN_NAME ="Data";    
    
    public File openBaseMap( Container container, JFrameMap jFrameBaseMap, StringBuilder polygonColumnName ) {
		File file =null;
        
        JFileChooser fileChooser = new JFileChooser();
		fileChooser.addChoosableFileFilter( new FileChooserFilter( FileChooserFilter.BASE_MAP_EXT ) );
		fileChooser.addChoosableFileFilter( new FileChooserFilter( FileChooserFilter.SHAPE_FILE_EXT ) );
		fileChooser.setCurrentDirectory( getBmaDir( container ) );
		
		// Open file dialog.
		int retVal =fileChooser.showOpenDialog(container);
		
		if ( retVal == JFileChooser.APPROVE_OPTION ) {		
			
		    file =fileChooser.getSelectedFile();			
		    logger.debug( "fileName=" + file.getAbsolutePath() );
		    setBmaDir( file.getParentFile() );
		 
		    if ( file.getAbsolutePath().toUpperCase().endsWith( FileChooserFilter.BASE_MAP_EXT.toUpperCase() ) ) {
		        BaseMapDAO dao;
                try {
                    dao = (BaseMapDAO)DAOFactory.getInstance().get( BizObjects.BASE_MAP );
                    BaseMap baseMap =(BaseMap)dao.load( file.getAbsolutePath() );
                    
                    if ( baseMap.getMinX() < jFrameBaseMap.getMappingToolKit().getMinX() 
                    		|| jFrameBaseMap.getMappingToolKit().getMinX() == 0 ) {
                    	jFrameBaseMap.getMappingToolKit().setMinX( baseMap.getMinX() );
                    }
                    
                    if ( baseMap.getMinY() < jFrameBaseMap.getMappingToolKit().getMinY()
                    		|| jFrameBaseMap.getMappingToolKit().getMinY() == 0 ) {
                    	jFrameBaseMap.getMappingToolKit().setMinY( baseMap.getMinY() );
                    }
                    
                    if ( baseMap.getMaxX() >  jFrameBaseMap.getMappingToolKit().getMaxX()
                    		|| jFrameBaseMap.getMappingToolKit().getMaxX() == 0 ) {
                    	jFrameBaseMap.getMappingToolKit().setMaxX( baseMap.getMaxX() );
                    }
                    
                    if ( baseMap.getMaxY() >  jFrameBaseMap.getMappingToolKit().getMaxY() 
                    		|| jFrameBaseMap.getMappingToolKit().getMaxY() == 0 ) {
                        jFrameBaseMap.getMappingToolKit().setMaxY( baseMap.getMaxY() );
                    }
                    
                    jFrameBaseMap.getMappingToolKit().addShapes( baseMap.getShapes() );
                    
                    // Process display factor based on shape file import
                    jFrameBaseMap.getMappingToolKit().processMapFactor();  
                    
                    jFrameBaseMap.getMappingToolKit().getThematicMap().getAnnotations().setTitlePt( null );
                    jFrameBaseMap.getMappingToolKit().getThematicMap().setDirty( true );  
                    
                    polygonColumnName.append( DEFAULT_JOIN_ID_COLUMN_NAME );                	

                } catch (Exception e1) {
                    miscUIHelper.displayErrorMessage( container, e1 );
                    file =null;
                }
		        
		    } else {
			    ShapeFileImport shapeFileImport =new ShapeFileImport();
			    try {
                    ShapeFile shapeFile =shapeFileImport.readShapeFile( file );
                    
                    int dbasePolygonIdx =-1;
                    
                    // Try to use the associated dbf file 
                    // for naming polygon if possible 
                    DBaseFile dbaseFile =null;
                    DBaseFileReader dbaseReader =new DBaseFileReader();
                    try  {
                    	File dbaseFilename =dbaseReader.convertShapeFileNameToDBaseFileName( file );
                    	dbaseFile =dbaseReader.readDBaseFile( dbaseFilename );
                    	if ( dbaseFile != null ) {
                    		JDialogSelectPolygonNameColumn jDlg 
                    			=new JDialogSelectPolygonNameColumn( JOptionPane.getFrameForComponent(jFrameBaseMap)
                    											   , true, dbaseFilename.getAbsolutePath() );
                    		jDlg.setVisible( true );
                    		
                    		if ( !jDlg.isCancelled() ) {
                    			// -1 because of a "please select" first entry in the combo box
                    			dbasePolygonIdx =jDlg.getSelectedColumnIndex()-1;
                    			polygonColumnName.append( jDlg.getSelectedColumnName() );
                    		}
                    		
                    		jDlg.dispose();
                    	}
                    } catch( Exception e ) {
                    	logger.error( e );
                    }
                    
                    //if ( dbasePolygonIdx != -1 ) {
                    new ShapeFileToBaseMapHelper().convert( jFrameBaseMap.getMappingToolKit(), shapeFile, dbaseFile, dbasePolygonIdx );
                    jFrameBaseMap.getMappingToolKit().getThematicMap().getAnnotations().setTitlePt( null );
                    jFrameBaseMap.getMappingToolKit().getThematicMap().setDirty( true );
                    //jFrameBaseMap.getMappingToolKit().setDbasePolygonIdx( dbasePolygonIdx );
                    //}

                } catch (Exception e2 ) {
                    miscUIHelper.displayErrorMessage( container, e2 );
                    file =null;
                }       
		    }
		    
		    container.repaint();
	    
		}
		
		return file;
    }
    
    public File saveBaseMap( Container container, JFrameMap jFrameBaseMap ) {
        if ( jFrameBaseMap.getBaseMap() != null && jFrameBaseMap.getBaseMap().getFile() != null ) {
            save( container, jFrameBaseMap, jFrameBaseMap.getBaseMap().getFile() );
            return  jFrameBaseMap.getBaseMap().getFile();
        } else {
            return saveBaseMapAs( container, jFrameBaseMap );
        }
    }
    
	public File saveBaseMapAs( Container container, JFrameMap jFrameBaseMap ) {
	    File file =null;
	    
		JFileChooser fileChooser = new JFileChooser();
		FileChooserFilter defaultFilter =new FileChooserFilter( FileChooserFilter.BASE_MAP_EXT );
		fileChooser.addChoosableFileFilter( defaultFilter );
		fileChooser.addChoosableFileFilter( new FileChooserFilter( FileChooserFilter.SHAPE_FILE_EXT ) );		
		fileChooser.setCurrentDirectory( getBmaDir( container ) );
		fileChooser.setFileFilter( defaultFilter );
		
		// Open file dialog.
		int retVal =fileChooser.showSaveDialog(container);
		
		if ( retVal == JFileChooser.APPROVE_OPTION ) {
			file =fileChooser.getSelectedFile();
		    logger.debug( "selectedFile=[" + file + "]" );
		    setBmaDir( file.getParentFile() );

	        if ( file.exists() ) {

	            int n =JOptionPane.showConfirmDialog( container,
	                    "This file already exists. Do you want to erase it?",
	                    "Save Base Map",
	                    JOptionPane.YES_NO_OPTION);
	            if ( n == JOptionPane.NO_OPTION ) {
	                file =null;
	            }
	        }
	        
	        if ( file != null ) {
	    		logger.debug( "fileName=" + file );
	    		
	        	// add extension if necessary
	        	if ( !file.getAbsolutePath().toLowerCase().endsWith( FileChooserFilter.BASE_MAP_EXT ) 
	        		&& !file.getAbsolutePath().toLowerCase().endsWith( FileChooserFilter.SHAPE_FILE_EXT )
	        		&& file.getName().indexOf(".") == -1 ) {
	        		file =new File( file.getAbsolutePath() + "." + ((FileChooserFilter)fileChooser.getFileFilter()).getExtension() );
	        	}	    		

	    		save( container, jFrameBaseMap, file );
	           
	        }
		}
	    
	    return file;
	}   
	
	private void save( Container container, JFrameMap jFrameBaseMap, File file ) {
		try {
			MappingToolKit mtk =jFrameBaseMap.getMappingToolKit();
			
            BaseMap baseMap =(BaseMap)BizObjectFactory.getInstance().get( BizObjectFactory.BASE_MAP );
            baseMap.setShapes( mtk.getShapes() );
            
            baseMap.setMinX( mtk.getMinX() );
            baseMap.setMinY( mtk.getMinY() );
            baseMap.setMaxX( mtk.getMaxX() );
            baseMap.setMaxY( mtk.getMaxY() );           
            
            baseMap.setDbaseJoinIdx( mtk.getDbaseJoinIdx() );
            
            Attrs attrs =mtk.getThematicMap() != null ? mtk.getThematicMap().getData() : null;
            
            if ( file.getAbsoluteFile().toString().toLowerCase().endsWith( FileChooserFilter.BASE_MAP_EXT ) ) {
            	BaseMapDAO dao =(BaseMapDAO)DAOFactory.getInstance().get( DAOFactory.BASE_MAP );
            	dao.save( file.getAbsolutePath(), baseMap );
            } else if ( file.getAbsoluteFile().toString().toLowerCase().endsWith( FileChooserFilter.SHAPE_FILE_EXT ) ) {
            	new ShapeFileExport().writeShapeFile( baseMap, attrs, file );
            }
            
            baseMap.setDirty( false );
        } catch (Exception e1) {
            miscUIHelper.displayErrorMessage( container, e1 );
        }	    
	}
	
	public void newBaseMap( JFrameMap jFrameMap ) {
		
		ThematicMap thematicMap =jFrameMap.getMappingToolKit().getThematicMap();
		ThematicMap shallowCopy =thematicMap.shallowClone();
		undoManager.clear();
	    jFrameMap.getMappingToolKit().reset();
	    shallowCopy.setBaseMap( null );
	    jFrameMap.getMappingToolKit().setThematicMap( shallowCopy );
	    jFrameMap.resetZoom();	
	    jFrameMap.setGeoBoxNotInitializedAlreadyWarned( false );
	    
	    thematicMap.setDirty( true );
	}

}
